-
-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DuckDBAppender: Add enum support #210
Conversation
Pull Request Test Coverage Report for Build 10453973952Details
💛 - Coveralls |
Thanks for the PR, looks good! Some comments:
|
Hi @Giorgi, thanks for the feedback. I will add the missing tests and also check what happens if an enum value is out of range. Regarding your second point: It is currently possible with the latest released version of DuckDB.NET to use string parameters to set enum fields. It would make sense to me if the Here is my example code where I use string parameters to set an enum field: using System.Data;
using DuckDB.NET.Data;
File.Delete("file.db");
using var duckDBConnection = new DuckDBConnection("Data Source=file.db");
duckDBConnection.Open();
using var command = duckDBConnection.CreateCommand();
command.CommandText = "CREATE TYPE test_enum AS ENUM ('test1', 'test2', 'test3')";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE test (a test_enum not null);";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO test (a) VALUES ($a);";
foreach (var enumValue in new string[] { "test1", "test2", "test3" })
{
command.Parameters.Clear();
command.Parameters.Add(new DuckDBParameter("a", enumValue));
command.ExecuteNonQuery();
}
command.CommandText = "SELECT a FROM test;";
var reader = command.ExecuteReader();
while (reader.Read())
{
string enumValue = reader.GetString("a");
Console.WriteLine(enumValue);
} @Giorgi With the above explanation, is it ok for you if we support writing strings to an Enum column? Kind regards |
Hi @Giorgi, something related. As far as I understand it, in DuckDB.NET the enum values are mapped via the numeric value and not according to the enum value names. In the Npgsql library, for example, the enum value name is used for the mapping. I would prefer such an approach. See the following example code: using System.Data;
using Npgsql;
using NpgsqlTypes;
var connectionString = "Host=127.0.0.1;Username=postgres;Password=xxx;Database=test_npgsql";
var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);
dataSourceBuilder.MapEnum<TestEnum>();
var dataSource = dataSourceBuilder.Build();
var npgsqlConnection = dataSource.OpenConnection();
using var command = npgsqlConnection.CreateCommand();
command.CommandText = "DROP TABLE IF EXISTS test;";
command.ExecuteNonQuery();
command.CommandText = "DROP TYPE IF EXISTS test_enum;";
command.ExecuteNonQuery();
command.CommandText = "CREATE TYPE test_enum AS ENUM ('test1', 'test2', 'test3')";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE test (a test_enum not null);";
command.ExecuteNonQuery();
npgsqlConnection.ReloadTypes();
command.CommandText = "INSERT INTO test (a) VALUES (:a);";
foreach (var enumValue in new string[] { "test1", "test2", "test3" })
{
command.Parameters.Clear();
command.Parameters.Add(new NpgsqlParameter("a", enumValue) { DataTypeName = "test_enum" });
command.ExecuteNonQuery();
}
command.CommandText = "SELECT a FROM test ORDER BY a ASC;";
var reader = command.ExecuteReader();
while (reader.Read())
{
TestEnum enumValue = reader.GetFieldValue<TestEnum>("a");
Console.WriteLine(enumValue);
}
public enum TestEnum
{
[PgName("test3")]
Test_3,
[PgName("test2")]
Test_2,
[PgName("test1")]
Test_1,
} @Giorgi Do we want to change this? Kind regards |
Ok, let's keep strings too. In such case can you move Also, can you update the test to read the Enum that was appended as string in the Enum type and vice-versa to test all the combinations? Thanks! |
I think this won't work with Appender because when appending string as Enum we don't know the underlying C# Enum. |
Hi @Giorgi, i think i could get the mapping working, my question is more, if mapping enums by name would be also a better approach for you? :) In my opinion, this approach is less error-prone. |
Let's keep it as it is for now. |
Ok, I'll make the necessary changes as discussed. |
…ndle is released too early
Hi @Giorgi, I implemented all the discussed changes, except the lazy initialization of the During writing the list tests I noticed that the logical type handle is released earlier than expected, so a lazy initialization is currently not so easy to implement (at least for me). Can you please review the PR again? Kind regards |
I'll review it later today. Why did you need to add |
The cast to |
Hello,
the
DuckDBAppender
class now supports adding enum values.I want to get some feedback from you @Giorgi, if the code is ok and if i should improve the error handling in the
EnumVectorDataWriter
class?I can also add additional tests if needed.
Issue: #209
Kind regards
Stefan